package com.youkeyi.ddy.cloud.application.business.storage.vaccinum.controller;

import com.youkeyi.ddy.cloud.common.api.application.business.storage.vaccinum.BusinessVaccinumPlanCloudService;
import com.youkeyi.ddy.cloud.common.api.application.business.storage.vaccinum.dto.BusinessVaccinumPlanListCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.business.storage.vaccinum.dto.BusinessVaccinumPlanListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.business.storage.vaccinum.param.BusinessVaccinumPlanCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.storage.vaccinum.StorageVaccinumCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.storage.vaccinum.dto.StorageVaccinumListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.storage.vaccinum.param.StorageVaccinumQueryCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicStorageConstant;
import com.youkeyi.ddy.cloud.common.context.YoukeyiSystemContext;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.utils.SystemDateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * BusinessVaccinumPlanController
 *
 * @Author liuxiawang
 * @Date 2024/3/25 11:41 AM
 * @Location shenzhen.china
 */
@Slf4j
@Service
public class BusinessVaccinumPlanController implements BusinessVaccinumPlanCloudService {

    @Autowired
    private StorageVaccinumCloudService storageVaccinumCloudService;

    @Override
    public BusinessVaccinumPlanListCloudDto plan(BusinessVaccinumPlanCloudParam param) {
        BusinessVaccinumPlanListCloudDto dto = new BusinessVaccinumPlanListCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param || null == param.getBirthday()) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        // 查询儿童打的疫苗
        StorageVaccinumQueryCloudParam vaccinumQueryCloudParam = new StorageVaccinumQueryCloudParam();
        vaccinumQueryCloudParam.setCorpKeys(Collections.singletonList(corpKey));
        vaccinumQueryCloudParam.setVaccinationPopulations(Collections.singletonList(YoukeyiDdyCloudBasicStorageConstant.STORAGE_VACCINATION_POPULATIONS_CHILD.value()));
        StorageVaccinumListCloudDto vaccinumDtos = storageVaccinumCloudService.query(vaccinumQueryCloudParam);
        if (null != vaccinumDtos && CollectionUtils.isNotEmpty(vaccinumDtos.getRows())) {
            List<BusinessVaccinumPlanListItemCloudDto> items = new ArrayList<>();

            String month = "%s个月";
            String remark = "第%s针";
            vaccinumDtos.getRows().forEach(vaccinumDto -> {
                if (null != vaccinumDto.getVaccinationFrequency()) {
                    Integer addMonthNumber = 0;
                    for (int i = 1; i <= vaccinumDto.getVaccinationFrequency(); i++) {
                        if (i == 1) {
                            if (null == vaccinumDto.getPlanOne()) {
                                break;
                            }
                            addMonthNumber = vaccinumDto.getPlanOne();
                            // 当前时间 距离 出生日期，过了几个月了呢？
                            Integer periodsMonth = SystemDateUtils.getPeriodsMonth(param.getBirthday(), System.currentTimeMillis());

                            BusinessVaccinumPlanListItemCloudDto item = new BusinessVaccinumPlanListItemCloudDto();
                            item.setVaccinumName(vaccinumDto.getName());
                            item.setMonth(periodsMonth < 1 ? "出生" : String.format(month, periodsMonth));
                            item.setInoculabilityTime(SystemDateUtils.endTimestamp(param.getBirthday(), vaccinumDto.getPlanOne()));
                            item.setRemark(String.format(remark, i));
                            items.add(item);
                        }
                        else if (i == 2) {
                            if (null == vaccinumDto.getPlanTwo()) {
                                break;
                            }
                            addMonthNumber = addMonthNumber + vaccinumDto.getPlanTwo();

                            BusinessVaccinumPlanListItemCloudDto item = new BusinessVaccinumPlanListItemCloudDto();
                            item.setVaccinumName(vaccinumDto.getName());
                            item.setMonth(String.format(month, addMonthNumber));
                            item.setInoculabilityTime(SystemDateUtils.endTimestamp(param.getBirthday(), addMonthNumber));
                            item.setRemark(String.format(remark, i));
                            items.add(item);
                        }
                        else if (i == 3) {
                            if (null == vaccinumDto.getPlanThree()) {
                                break;
                            }
                            addMonthNumber = addMonthNumber + vaccinumDto.getPlanThree();

                            BusinessVaccinumPlanListItemCloudDto item = new BusinessVaccinumPlanListItemCloudDto();
                            item.setVaccinumName(vaccinumDto.getName());
                            item.setMonth(String.format(month, addMonthNumber));
                            item.setInoculabilityTime(SystemDateUtils.endTimestamp(param.getBirthday(), addMonthNumber));
                            item.setRemark(String.format(remark, i));
                            items.add(item);
                        }
                        else if (i == 4) {
                            if (null == vaccinumDto.getPlanFour()) {
                                break;
                            }
                            addMonthNumber = addMonthNumber + vaccinumDto.getPlanFour();

                            BusinessVaccinumPlanListItemCloudDto item = new BusinessVaccinumPlanListItemCloudDto();
                            item.setVaccinumName(vaccinumDto.getName());
                            item.setMonth(String.format(month, addMonthNumber));
                            item.setInoculabilityTime(SystemDateUtils.endTimestamp(param.getBirthday(), addMonthNumber));
                            item.setRemark(String.format(remark, i));
                            items.add(item);
                        }
                        else if (i == 5) {
                            if (null == vaccinumDto.getPlanFive()) {
                                break;
                            }
                            addMonthNumber = addMonthNumber + vaccinumDto.getPlanFive();

                            BusinessVaccinumPlanListItemCloudDto item = new BusinessVaccinumPlanListItemCloudDto();
                            item.setVaccinumName(vaccinumDto.getName());
                            item.setMonth(String.format(month, addMonthNumber));
                            item.setInoculabilityTime(SystemDateUtils.endTimestamp(param.getBirthday(), addMonthNumber));
                            item.setRemark(String.format(remark, i));
                            items.add(item);
                        }
                    }
                }
            });

            // 按照疫苗接种时间升序且按照疫苗名称升序
            items.stream()
                    .filter(i -> i.getInoculabilityTime() > System.currentTimeMillis()).collect(Collectors.toList())
                    .sort(Comparator.comparingLong(BusinessVaccinumPlanListItemCloudDto::getInoculabilityTime)
                            .thenComparing(BusinessVaccinumPlanListItemCloudDto::getVaccinumName)
            );

            dto.setRows(items);
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public void exportXls(HttpServletResponse response, BusinessVaccinumPlanCloudParam param) {
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            log.error(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return;
        }
        if (null == param || null == param.getBirthday()) {
            log.error(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return;
        }

        // 创建一个webbook,对应一个Excel文件夹
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
        XSSFSheet sheet = workbook.createSheet("疫苗接种计划");
        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        XSSFRow row = sheet.createRow(0);
        // 创建一个居中格式
        XSSFCellStyle style = workbook.createCellStyle();
        // 创建一个居中格式
        style.setAlignment(HorizontalAlignment.CENTER);
        int rowNum = 1;
        // 设置每列标题
        String[] headers = {"疫苗项目", "打针", "打针月份", "针数"};
        // 在excel表中添加表头
        for (int i = 0; i < headers.length; i++) {
            XSSFCell cell = row.createCell(i);
            XSSFRichTextString text = new XSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }

        // 第一行
        XSSFRow row1 = sheet.createRow(rowNum);
        row1.createCell(0).setCellValue(String.format("宝宝姓名：%s", param.getName()));
        row1.createCell(1).setCellValue("");
        row1.createCell(2).setCellValue("");
        row1.createCell(3).setCellValue("备注");
        rowNum++;
        // 第二行
        XSSFRow row2 = sheet.createRow(rowNum);
        row2.createCell(0).setCellValue(String.format("宝宝的出生日期：%s", SystemDateUtils.ofPattern(param.getBirthday(), "yyyy-MM-dd")));
        rowNum++;

        BusinessVaccinumPlanCloudParam planParam = new BusinessVaccinumPlanCloudParam();
        planParam.setName(param.getName());
        planParam.setBirthday(planParam.getBirthday());
        BusinessVaccinumPlanListCloudDto planDtos = this.plan(planParam);
        if (null != planDtos && CollectionUtils.isNotEmpty(planDtos.getRows())) {
            // excel row
            for (BusinessVaccinumPlanListItemCloudDto plan : planDtos.getRows()) {
                XSSFRow rowN = sheet.createRow(rowNum);
                rowN.createCell(0).setCellValue(plan.getVaccinumName());
                rowN.createCell(1).setCellValue(plan.getMonth());
                rowN.createCell(2).setCellValue(null != plan.getInoculabilityTime() ? SystemDateUtils.ofPattern(plan.getInoculabilityTime(), "yyyy-MM-dd") : "-");
                rowN.createCell(3).setCellValue(plan.getRemark());
                rowNum++;
            }
        }

        try {
            String fileName = "vaccinum-plan.xlsx";
            response.reset(); // 必要地清除response中的缓存信息
            response.setContentType("application/msexcel;charset=utf-8");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setDateHeader("Expires", 0);
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Content-disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\""+".xlsx");
            OutputStream osOut = response.getOutputStream();
            workbook.write(osOut);
            osOut.flush();
            osOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
